home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 00 / 5 / DISK0050.ZIP / ROFF1.C < prev    next >
Text File  |  1982-09-01  |  11KB  |  452 lines

  1. #define FALSE 0
  2. #define TRUE 1
  3.  
  4. /* 7 MAY 81 */
  5. /* based on the formatter presented in Kernighan and Plauger's
  6. SOFTWARE TOOLS, modified for BDS C */
  7.  
  8.  
  9.  
  10. #include "stdio.h"
  11. #include "ctype.h"
  12. #include "ROFF.H"
  13.  
  14.  
  15. main(argc, argv)
  16. int argc;
  17. char **argv;
  18. {
  19.    char filename[20];
  20.    char line[MAXLINE];
  21.    struct _iobuf *bufr;
  22.  
  23.  
  24.     errprnt("\nVersion 5.1\n");
  25.  
  26.     debug = FALSE;
  27.     if (argc == 1)
  28.     { errprnt("\nUSAGE:  roff >destination origin_file \n");
  29.       errprnt("Where origin_file is any valid text file name\n");
  30.       errprnt("And destination is a filename, or LST: (printer)\n");
  31.       errprnt("\tor left out (to console)\n");
  32.         exit();
  33.     }
  34.  
  35.     argv++;
  36.     while ( --argc > 0 )
  37.     { strcpy (filename, *argv++);        /* get next argument */
  38.         errprnt("\nNow processing <%s>",filename );
  39.         if (filename[0] == '-' && filename[1]=='d')
  40.         {
  41.             debug=TRUE;
  42.             continue;
  43.         }
  44.  
  45.  
  46.         if ((bufr = fopen(filename, "r")) == NULL)
  47.         { errprnt("\ncan not open <%s>", filename );
  48.             continue;
  49.         }
  50.  
  51.         init_defaults();
  52.  
  53.         while ( fgets( line,MAXLINE, bufr ) != 0 ) /*until EOF or CPMEOF */
  54.         { if (line[0] == COMMAND )
  55.                 comand (line);
  56.             else
  57.                 text (line);
  58.  
  59.         }
  60.         if (LINENO > 0  || OUTBUF[0] !='\0')
  61.             space (HUGE);        /* flush last output */
  62.         errprnt("\nDone processing <%s>", filename );
  63.  
  64.     }     /* end while (--argc > 0 ) */
  65.     exit(0);
  66. }        /* end main()           */
  67.  
  68.  
  69. /********************************************************************
  70. initializes the global variables governing the execution of the
  71.  format commands.
  72. ********************************************************************/
  73. init_defaults()
  74. {
  75.  
  76.     FILL = FI_DEF;    /* yes we want filled lines */
  77.     LSVAL = LS_DEF;    /* line spacing = 1 */
  78.     INVAL = IN_DEF;    /* left margin indent  0 */
  79.     RMVAL = RM_DEF;    /* right margin = page width  */
  80.     TIVAL = TI_DEF;    /* left margin temporary indent    0 */
  81.     CEVAL = CE_DEF;    /* next n lines to be centered -  0  */
  82.     ULVAL = UL_DEF;    /* next n lines to be underlined -  0  */
  83.  
  84.     PAGESTOP = FALSE;
  85.     PLVAL = PAGELEN;
  86.     M1VAL = M1_DEF;        /* top and bottom margins */
  87.     M2VAL = M2_DEF;
  88.     M3VAL = M3_DEF;
  89.     M4VAL = M4_DEF;
  90.     CURPAG = 0;
  91.     NEWPAG = 1;
  92.     LINENO = 0;
  93.     BOTTOM = PLVAL - M3VAL - M4VAL;
  94.  
  95.     OUTWRDS = 0;    /* no. of words in outbuf */
  96.     OUTBUF [0] = '\0';
  97.     DIR = 0;
  98.  
  99.     strcpy ( HEADER, "\n" );
  100.     strcpy ( FOOTER, "\n" );
  101. }
  102.  
  103.  
  104. /*****************************************************************
  105. this function decodes the command type, returning the type, or
  106.     UNKNOWN.
  107. *******************************************************************/
  108. int comtyp (line)
  109. char *line;
  110. {
  111.     char let1, let2;
  112.  
  113.     let1 = toupper( line[1] );
  114.     let2 = toupper( line[2] );
  115.  
  116.     if ( let1=='F' && let2=='I')    return( FI );
  117.     if ( let1=='F' && let2=='O')    return( FO );
  118.     if ( let1=='T' && let2=='I')    return( TI );
  119.     if ( let1=='B' && let2=='P')    return( BP );
  120.     if ( let1=='B' && let2=='R')    return( BR );
  121.     if ( let1=='C' && let2=='E')    return( CE );
  122.     if ( let1=='H' && let2=='E')    return( HE );
  123.     if ( let1=='I' && let2=='N')    return( IN );
  124.     if ( let1=='L' && let2=='S')    return( LS );
  125.     if ( let1=='N' && let2=='F')    return( NF );
  126.     if ( let1=='P' && let2=='L')    return( PL );
  127.     if ( let1=='R' && let2=='M')    return( RM );
  128.     if ( let1=='S' && let2=='P')    return( SP );
  129.     if ( let1=='U' && let2=='L')    return( UL );
  130.     if ( let1=='M')
  131.     { if (let2=='1')        return( M1 );
  132.         if (let2=='2')        return( M2 );
  133.         if (let2=='3')        return( M3 );
  134.         if (let2=='4')        return( M4 );
  135.     }
  136.  
  137.     return( UNKNOWN );        /* no match */
  138.  
  139. }
  140.  
  141.  
  142. /*********************************************************************
  143. Skips white-space characters at the beginning of a string.
  144. *********************************************************************/
  145. skip_blanks ( string )
  146. char *string;
  147. {
  148.     char local[ MAXLINE ];
  149.     int i, j, k;
  150.  
  151.  
  152.  
  153.     strcpy ( local, string );
  154.  
  155.     for (i=0; local[i]==' ' || local[i]=='\t' || local[i]=='\n' ; i++);
  156.  
  157.     for (j=0; (string[j]=local[i]) != '\0' ; i++, j++ )    ;
  158.  
  159.     return;
  160. }
  161.  
  162.  
  163. /*********************************************************************
  164.  
  165. Truncates white-space characters at the end of a string.
  166.  
  167. *********************************************************************/
  168. trunc_bl (string)
  169. char *string;
  170. {
  171.     char *ptr;
  172.     int k;
  173.  
  174.     k = strlen (string);
  175.     ptr = &string[ k-1 ];    /* char before terminating nul */
  176.  
  177.     while (*ptr==BLANK || *ptr==TAB || *ptr==NEWLINE)    
  178.         *ptr--  = '\0';
  179. }
  180.  
  181.  
  182. /*******************************************************************
  183. performs the formatting command returned by comtyp - sets global
  184.   variables ( indenting, underlining, etc. )
  185. *******************************************************************/
  186.  
  187. comand ( line )
  188. char *line;
  189. {
  190.     int c_type;    /* command type  */
  191.     int arg_val;    /* argument value, if any */
  192.     char arg_typ;    /* relative (+ or -) or absolute */
  193.     int i;
  194.  
  195.     c_type = comtyp (line);
  196.     if DEBUG errprnt("\n\nCOMAND %d",c_type);
  197.  
  198.     if (c_type == UNKNOWN)    /* IGNORE ALIEN ORDERS */
  199.     {
  200.         errprnt( "UNKNOWN COMMAND: <%s>\n", line);
  201.         return;
  202.     }
  203.  
  204.     arg_val = get_val ( line, &arg_typ );
  205.     if DEBUG errprnt( " \n    get_val returned arg_val=%d, arg_typ= %c   ",
  206.       arg_val,    arg_typ   );
  207.     if DEBUG errprnt("\n\n");
  208.  
  209.     switch (c_type)
  210.     {
  211.     case FI :    /* filled lines  */
  212.         brk();    /* flush out last unfilled */
  213.         FILL = YES;
  214.         break;
  215.  
  216.     case NF :    /* non-filled lines */
  217.         brk();    /* flush out */
  218.         FILL = NO;
  219.         break;    /* down and cry */
  220.  
  221.     case BR :    /* just cause a break */
  222.         brk();
  223.         break;
  224.  
  225.     case LS :    /* set line spacing value */
  226.         set (&LSVAL, arg_val, arg_typ, LS_DEF, 1, HUGE );
  227.         break;
  228.  
  229.     case TI :    /* set temporary left indent */
  230.         brk();
  231.         set ( &TIVAL, arg_val, arg_typ, TI_DEF, 0, RMVAL );
  232.         break;
  233.  
  234.     case IN :    /* set left indent */
  235.         set ( &INVAL, arg_val, arg_typ, IN_DEF, 0, RMVAL-1 );
  236.         TIVAL = INVAL;
  237.         break;
  238.  
  239.     case RM:    /* set right margin */
  240.         set ( &RMVAL, arg_val, arg_typ, RM_DEF, TIVAL+1, HUGE );
  241.         break;
  242.     case M1:    /* set topmost margin */
  243.         set ( &M1VAL, arg_val, arg_typ, M1_DEF, 0, HUGE);
  244.         break;
  245.  
  246.     case M2:    /* set second top margin */
  247.         set ( &M2VAL, arg_val, arg_typ, M2_DEF, 0, HUGE);
  248.         break;
  249.  
  250.     case M3:    /* set first bottom margin */
  251.         set ( &M3VAL, arg_val, arg_typ, M3_DEF, 0, HUGE);
  252.         break;
  253.  
  254.     case M4:    /* set bottom-most margin */
  255.         set ( &M4VAL, arg_val, arg_typ, M4_DEF, 0, HUGE);
  256.         break;
  257.  
  258.     case CE :    /* center next arg_val lines */
  259.         brk();
  260.         set ( &CEVAL, arg_val, arg_typ, CE_DEF, 0, HUGE);
  261.         break;
  262.  
  263.     case UL :    /* underline next arg_val lines */
  264.         set ( &ULVAL, arg_val, arg_typ, UL_DEF, 1, HUGE );
  265.         break;
  266.  
  267.     case HE :    /* get header title for pages */
  268.         gettl ( line, HEADER );
  269.         break;
  270.  
  271.     case FO :    /* get footer title for pages */
  272.         gettl ( line, FOOTER );
  273.         break;
  274.  
  275.     case SP :    /* space down arg_val blank lines */
  276.         set (&SPVAL, arg_val, arg_typ, 1, 0, HUGE);
  277.         space ( SPVAL );
  278.         break;
  279.  
  280.     case BP :    /* set pageno arg_val - begin page */
  281.         if ( LINENO > 0 )    space (HUGE);
  282.         set ( &CURPAG, arg_val, arg_typ, CURPAG+1, -HUGE, HUGE);
  283.         NEWPAG = CURPAG;
  284.         break;
  285.  
  286.     case PL :    /* set page length */
  287.         set (&PLVAL, arg_val, arg_typ, PAGELEN,
  288.           M1VAL+M2VAL+M3VAL+M4VAL+1, HUGE);
  289.         BOTTOM = PLVAL - M3VAL - M4VAL;
  290.         break;
  291.  
  292.  
  293.     }
  294.  
  295.     return;
  296. }
  297.  
  298. /******************************************************************
  299.  
  300. gets the number ( if any ) associated with any command 
  301.  
  302. *******************************************************************/
  303. int get_val ( line, typ )
  304. char *line, *typ;
  305. {
  306.     int i,j;
  307.     char local[ MAXLINE ];
  308.  
  309.     strcpy (local, line);    /* local copy */
  310.  
  311. /* skip over the command line */
  312.     for (i=1; local[i]!=' ' && local[i]!='\t' && local[i]!='\n' ; i++ )
  313.         ;
  314.  
  315.     skip_blanks (&local[i]);    /* find the number */
  316.     *typ = local[i];    /* relative or absolute */
  317.  
  318.     if ( *typ=='+' || *typ=='-' )    i++;
  319.     else if ( !isdigit( *typ ) )    return( NO_VAL );
  320.  
  321.     stcd_i( &local[i], &j);
  322.     return(j);
  323.  
  324. }
  325.  
  326.  
  327. /*****************************************************************
  328.  sets a global parameter like line-spacing, underlining, etc.
  329.  Also checks that the new value is within the range of that 
  330.  parameter.  Assigns the default for that parameter if no value
  331.   is specified.
  332. ******************************************************************/
  333.  
  334. set ( param, val, arg_typ, defval, minval, maxval )
  335. int *param, val, defval, minval, maxval;
  336. char arg_typ;
  337. {
  338.     if (val == NO_VAL )        /* defaulted */
  339.         *param = defval;
  340.     else if (arg_typ == '+')    /* relative + */
  341.         *param += val;
  342.     else if (arg_typ == '-')    /* relative - */
  343.         *param -= val;
  344.     else    *param = val;        /* absolute */
  345.  
  346.     *param = min(*param,maxval);
  347.     *param = max(*param, minval);
  348.  
  349.     if DEBUG errprnt("\n    SET *param = %d", *param);
  350.     return;
  351. }
  352.  
  353.  
  354.  
  355. /**********************************************************
  356.         centers a line of text
  357. **********************************************************/
  358. center (line)
  359. char *line;
  360. {
  361.     TIVAL = max(( RMVAL+TIVAL-strlen(line))/2, 0 );
  362.     return;
  363. }
  364.  
  365.  
  366. /**************************************************************
  367.     get next word from input line
  368. *************************************************************/
  369. int getwrd (in,  out )
  370. char *in, *out;
  371. {
  372.     int i, j, n;
  373.  
  374. /* find first non-blank */
  375.     skip_blanks (in);
  376.     replace_char ( in, TAB, BLANK); /* replace tabs w/space */
  377.  
  378. /* scan off a word */
  379.     if ( 1 == (n = movwrd( in, out)))
  380.     { if DEBUG errprnt("\nafter sscanf out = <%s>",out);
  381.         j = strlen (out);
  382.         replace_char (out, NEWLINE, BLANK);
  383.         for (i=0; i<j; i++ )    in[i] = BLANK;    /* blank out word in input */
  384.     }
  385.     if DEBUG errprnt("\ngetwrd will return %d", n);
  386.     return(n);    /* WE_HAVE_A_WORD = 1 */
  387. }
  388.  
  389.  
  390.  
  391.  
  392. /*****************************************************************
  393.     distibute words evenly across a line
  394. *****************************************************************/
  395. spread ( line, nextra, no_words)
  396. char *line;
  397. int nextra;    /* no. extra places left in line */
  398. int no_words;   /* no. words in the line         */
  399. {
  400.     int i, j, nblanks, nholes;
  401.  
  402.     if (nextra <= 0 || no_words <= 1)    return;
  403.  
  404.     DIR = !(DIR);
  405.     nholes = no_words - 1;
  406.     trunc_bl (line);
  407.     i = strlen(line) - 1 ; /* last character of string */
  408.     j = min(MAXLINE - 2,  i + nextra);    /* last  position in output */
  409.     line[j+1] = '\0';
  410.  
  411.     for ( ; i<j ; i--, j-- )
  412.     { line[j] = line[i];
  413.         if DEBUG errprnt("[%c i=%d j=%d] ", line[j], i, j);
  414.         if ( line[i] == BLANK)
  415.         { if (DIR == 0)
  416.                 nblanks = (nextra - 1)/nholes   +   1;
  417.             else
  418.                 nblanks = nextra/nholes;
  419.             nextra = nextra - nblanks;
  420.             nholes = nholes - 1;
  421.  
  422.             if DEBUG errprnt("\nnblanks=%d, nextra=%d",
  423.               nblanks,    nextra   );
  424.             for ( ; nblanks > 0;  nblanks-- )
  425.                 line[--j] = BLANK;
  426.         }
  427.     }
  428.     if DEBUG errprnt("\nafter spreading, line is:\n<%s>", line);
  429.     return;
  430. }
  431.  
  432.  
  433. /****************************************************************
  434.     end current filled line 
  435. *****************************************************************/
  436. brk()
  437. {
  438.     int l;
  439.     if DEBUG errprnt("\nbrk: OUTBUF=<%s>", OUTBUF);
  440.  
  441.     if ( 0!= ( l = strlen (OUTBUF)))
  442.     { OUTBUF[l] = NEWLINE;
  443.         OUTBUF[l+1] = '\0';
  444.         put (OUTBUF);
  445.     }
  446.  
  447.     OUTWRDS = 0;
  448.     OUTBUF[0] = '\0';
  449.     return;
  450.  
  451. }
  452.